﻿using System;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Diagnostics;
using System.Text.RegularExpressions;
using Business;
using EntityReflect;
using PowerS.Properties;

namespace PowerS
{
    public partial class PowerSForm : Form
    {
        private Point _pi;
        private DateTime _currentMonth = DateTime.Now;

        public PowerSForm()
        {
            InitializeComponent();
            RefreshTreeNodes();
        }

        /// <summary>
        /// 根据月份显示图表
        /// </summary>
        /// <param name="selectedMonth"></param>
        private void UpdateChart(DateTime selectedMonth)
        {
            _currentMonth = selectedMonth;
            toolStripTextBox1.Text = string.Format("{0}-{1}", selectedMonth.Year.ToString(), selectedMonth.Month.ToString());

            var ds = BusinessLogic.QueryMonthDataSet(selectedMonth);

            powerChart.Series[0].Points.Clear();
            foreach (DataTable dt in ds.Tables)
            {
                int i = 0;
                foreach (DataRow dr in dt.Rows)
                {
                    DateTime pOnTime = Convert.ToDateTime(dr[1]);
                    DateTime pOffTime = Convert.ToDateTime(dr[2]);
                    var timeSpan = new TimeSpan(Convert.ToInt64(dr[3]));
                    String onToOffStr = string.Format("{0}--{1}", pOnTime.ToString(), pOffTime.ToString());
                    String durationStr = "Duration: " + timeSpan.Duration();
                    String barTips = string.Format("{0}\n{1}", onToOffStr, durationStr);
                    if (pOnTime.Date == pOffTime.Date)
                    {
                        //开机关机在同一天
                        powerChart.Series[0].Points.AddXY(pOnTime.Date, pOnTime.ToString("HH:MM:ss"), pOffTime.ToString("HH:MM:ss"));
                        powerChart.Series[0].Points[i].ToolTip = barTips;
                        i++;
                    }
                    else
                    {
                        //开机关机不在同一天,跨天会分开显示,但是Tips相同
                        TimeSpan myTimeSpan = (pOffTime).Subtract(pOnTime);

                        powerChart.Series[0].Points.AddXY(pOnTime.Date, pOnTime.ToString("HH:MM:ss"), "23:59:59");
                        powerChart.Series[0].Points[i].ToolTip = barTips;
                        i++;
                        for (int j = 1; j <= myTimeSpan.Days; j++)
                        {
                            if (j == myTimeSpan.Days)
                            {
                                powerChart.Series[0].Points.AddXY(pOffTime.Date, "00:00:00", pOffTime.ToString("HH:MM:ss"));
                            }
                            else
                            {
                                powerChart.Series[0].Points.AddXY(pOnTime.Date.AddDays(j), "00:00:00", "23:59:59");
                            }
                            powerChart.Series[0].Points[i].ToolTip = barTips;
                            i++;
                        }
                    }

                }
            }
        }


        #region 读取日志并写入数据库
        /// <summary>
        /// 重新读取日志刷新数据
        /// </summary>
        private void RefreshData()
        {
            if (backgroundWorker1.IsBusy)
            {
                backgroundWorker1.CancelAsync();
                rfreshToolStripMenuItem.Text = Resources.PowerSForm_Refresh;
            }
            else
            {
                backgroundWorker1.RunWorkerAsync();
                rfreshToolStripMenuItem.Text = Resources.PowerSForm_RefreshData_STOP;
                toolStripButton1.Image = Resources.refresh_red;
            }

        }
        /// <summary>
        /// 后台进程开始,调用工作函数
        /// 这里，就是后台进程开始工作时，调用工作函数的地方。你可以把你现有的处理函数写在这儿。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            bool isSuccess = ReadLogUsingBGW(backgroundWorker1);
            Console.WriteLine(!isSuccess ? "Not Success" : "Success");
        }

        /// <summary>
        /// 真正的处理工作,后台处理读取数据
        /// </summary>
        /// <param name="bk"></param>
        /// <returns></returns>
        private bool ReadLogUsingBGW(BackgroundWorker bk)
        {

            var eventLog = new EventLog {Log = "System"};
            EventLogEntryCollection myCollection = eventLog.Entries;
            int i = 0;
            var record = new PowerRecord();

            (new BusinessLogic()).ClearDbTable();

            foreach (EventLogEntry eventLogEntry in myCollection)
            {
                //判断是否取消
                if (bk.CancellationPending)
                {
                    bk.ReportProgress(100 * i / myCollection.Count, String.Format("当前值是 {0},操作被用户申请中断", 100 * i / myCollection.Count));

                    return false;
                }

                if (eventLogEntry.InstanceId == 2147489653)//开机
                {
                    if (record.PowerOnTime == null) record.PowerOnTime = eventLogEntry.TimeWritten;


                }
                else if (eventLogEntry.InstanceId == 2147489654) //关机
                {

                    if (record.PowerOffTime == null && record.PowerOnTime != null)
                    {
                        record.PowerOffTime = eventLogEntry.TimeWritten;
                        record.Comment = "Normal off";
                        (new BusinessLogic()).Save(record);

                        record.PowerOnTime = null;
                        record.PowerOffTime = null;
                    }
                }
                else if (eventLogEntry.InstanceId == 2147489656)//异常关机再开机的时间
                {
                    record.PowerOffTime = GetLastOffTime(eventLogEntry.Message);
                    record.Comment = "Abnormal off";

                    (new BusinessLogic()).Save(record);

                    Console.WriteLine(eventLogEntry.TimeWritten + eventLogEntry.Message);
                    record.PowerOnTime = null;
                    record.PowerOffTime = null;
                }

                bk.ReportProgress(100 * i / myCollection.Count, String.Format("当前值是 {0} ", 100 * i / myCollection.Count));
                i++;

            }

            return true;
        }

        /// <summary>
        /// 利用正则来获取异常关机时间  
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static DateTime GetLastOffTime(string str)
        {
            str = Regex.Replace(str, @"[^0-9/: ]", "");
            DateTime lastOffTime = Convert.ToDateTime(str);
            Console.WriteLine(lastOffTime);
            return lastOffTime;
        }
        /// <summary>
        /// 读取时更新进度百分比
        /// 这里就是通过响应消息，来处理界面的显示工作
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            toolStripProgressBar1.Value = e.ProgressPercentage;

            toolStripProgressBar1.Text = e.UserState.ToString();
        }
        /// <summary>
        /// 读取完成后将进度条百分比置0,菜单刷新名字置回Refresh
        /// 这里是后台工作完成后的消息处理，可以在这里进行后续的处理工作。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            toolStripProgressBar1.Value = 0;
            rfreshToolStripMenuItem.Text = Resources.PowerSForm_Refresh;
            toolStripButton1.Image = Resources.refresh_green;
            RefreshTreeNodes();
        }
        #endregion

        #region 菜单项
        /// <summary>
        /// 菜单项--导出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void exportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            BusinessLogic.ExportCsvByMonth(_currentMonth);
        }
        /// <summary>
        /// 菜单项--刷新
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RefreshData();
        }
        /// <summary>
        /// 菜单项--退出
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }
        /// <summary>
        /// 菜单项--捐助,打开支付宝个人主页收款页面
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void donateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Process.Start("https://me.alipay.com/mpay");
        }

        /// <summary>
        /// 帮助
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            var abFrm = new AboutBox() { StartPosition = FormStartPosition.CenterScreen };

            abFrm.UpdateMainTitle += UpdateTitle;

            abFrm.ShowDialog(); //显示子窗口
        }

        private void UpdateTitle(string title)
        {
            Text = title;
        }

        #endregion

        #region 工具栏
        /// <summary>
        /// 点击工具栏按钮刷新读取系统日志
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            RefreshData();
        }

        /// <summary>
        /// 工具栏导出按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            BusinessLogic.ExportCsvByMonth(_currentMonth);
        }

        #endregion

        #region 树节点操作
        /// <summary>
        /// 根据数据库查询生成树节点
        /// </summary>
        private void RefreshTreeNodes()
        {
            treeView1.Nodes.Clear();
            //添加树节点
            const string sql = @"SELECT distinct format(PowerOnTime,'yyyy') FROM PowerTable";

            var bl = new BusinessLogic();
            DataSet ds =bl.QueryBySql(sql);

            if (ds.Tables.Count == 1 && ds.Tables[0].Rows.Count == 0)
            {
                label1.Visible = true;
                label1.Text = Resources.PowerSForm_RefreshTips;
                splitContainer1.Visible = false;
            }
            else
            {
                label1.Visible = false;
                splitContainer1.Visible = true;
                TreeNode node1 = null;
                foreach (DataTable dt in ds.Tables)
                {
                    foreach (DataRow dr in dt.Rows)
                    {
                        var yearNode = new TreeNode(dr[0].ToString());//构造父结点   
                        treeView1.Nodes.Add(yearNode);//添加父结点 

                        String getDistinctMonth = "Select distinct format(PowerOnTime,'mm') from PowerTable where PowerOnTime between #" + dr[0] + "-01-01" + "# AND #" + dr[0] + "-12-31#";

                        Console.WriteLine(getDistinctMonth);
                        var distinctMonthds = (new BusinessLogic()).QueryBySql(getDistinctMonth);

                        foreach (DataTable distinctMonthdt in distinctMonthds.Tables)
                        {
                            foreach (DataRow distinctMonthdr in distinctMonthdt.Rows)
                            {
                                node1 = new TreeNode(distinctMonthdr[0].ToString());//构造子结点   
                                yearNode.Nodes.Add(node1);//把子结点添加给父结点 
                            }
                        }

                    }
                }
                //根据最后一个节点显示当前图表
                if (node1 != null)
                {
                    DateTime selectedMonth = Convert.ToDateTime(node1.Parent.Text + "-" + node1.Text);
                    UpdateChart(selectedMonth);
                }
            }
        }
        /// <summary>
        /// 年月树节点的双击事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_DoubleClick(object sender, EventArgs e)
        {
            TreeNode node = treeView1.GetNodeAt(_pi);
            if (_pi.X < node.Bounds.Left || _pi.X > node.Bounds.Right)
            {
                return; //不触发事件
            }

            if (node.Parent != null)
            {
                DateTime selectedMonth = Convert.ToDateTime(node.Parent.Text + "-" + node.Text);
                UpdateChart(selectedMonth);
            }
        }
        /// <summary>
        /// 鼠标第一次按下时获取节点位置
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void treeView1_MouseDown(object sender, MouseEventArgs e)
        {
            _pi = new Point(e.X, e.Y);
        }
        #endregion


    }
}
